home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / QuickDraw GX / QuickDraw GX Info / QuickDraw GX Interfaces / Interfaces & Libraries / graphics libraries / arc library.c next >
Encoding:
C/C++ Source or Header  |  1994-04-30  |  4.9 KB  |  157 lines  |  [TEXT/MPS ]

  1. /* graphics libraries:
  2.     arc and wedge functions
  3.     by Mike Reed
  4.     ©1989 - 1991 Apple Computer, Inc.
  5.     All rights reserved.
  6.     
  7.     Sean Parent     - fixed bug (first pt off gxCurve)
  8.                 - added code to obey sweep direction (negative is counter-clockwise)
  9. */
  10.  
  11. #include "graphics libraries.h"
  12.  
  13.  
  14. /*
  15.   * Same as the QD call, but takes fixed parameters.  The wedge boolean is set to false for FrameArc
  16.   * and to true for everything else.
  17.   */
  18.  
  19. #define kFracCos45over2     0x3B20D79E
  20. #define kMaxArcPoints       13
  21.  
  22. typedef struct {
  23.     long count;
  24.     long ctrBits;
  25.     gxPoint data[kMaxArcPoints];      /* only need up to 12 + 1 for center of wedge */
  26. } tmpArcPathType;
  27.  
  28.  
  29. /*
  30.   * Used by NewArc and SetArc, it sets 'aPathPtr'
  31.   * (a tmpArcPathType) to the appropriate
  32.   * wedge gxShape.
  33.   */
  34. static void SetArcData(const gxRectangle *r, Fixed startAng, Fixed sweep, boolean wedge, tmpArcPathType *aPathPtr)
  35. {
  36.     register long *ptWalker;
  37.  
  38.     aPathPtr->count = 0;
  39.     aPathPtr->ctrBits = 0;
  40.     {
  41.         register            Fixed   halfWidth   = (r->right - r->left + 1) >> 1;
  42.         register            Fixed   halfHeight  = (r->top - r->bottom + 1) >> 1;
  43.         register            Fixed   sweepAng = sweep;
  44.         register            Fixed   midPointAng;
  45.         register unsigned   long    ctrBitMask = 0x40000000U;
  46.         register            short   i;
  47.                             Fixed   cosineValue;
  48.                             Fixed   incrementAng;
  49.                             Fixed   halfIncrementAng;
  50.  
  51.         if (sweep < 0) incrementAng = ff(-45);
  52.         else incrementAng = ff(45);
  53.         halfIncrementAng = incrementAng >> 1;
  54.  
  55.         midPointAng = startAng + halfIncrementAng;
  56.     /*
  57.       * Always set the first gxPoint
  58.       */
  59.         ptWalker = &aPathPtr->data[0].x;
  60.         *ptWalker++ = FractMultiply(FractSineCosine(startAng, &cosineValue), halfWidth);
  61.         *ptWalker++ = FractMultiply(cosineValue, halfHeight);
  62.  
  63.         for (i = FixedToInt(sweepAng) / FixedToInt(incrementAng) - 1; i >= 0; i--) {
  64.             *ptWalker++ = MultiplyDivide(halfWidth, FractSineCosine(midPointAng, &cosineValue), kFracCos45over2);
  65.             *ptWalker++ = MultiplyDivide(halfHeight, cosineValue, kFracCos45over2);
  66.             aPathPtr->ctrBits |= ctrBitMask;
  67.             midPointAng += incrementAng;
  68.             ctrBitMask >>= 1;
  69.             sweepAng -= incrementAng;
  70.         }
  71.     /*
  72.       * Finish with a short parabola if not on a 45 degree multiple
  73.       */
  74.         if (sweepAng != 0)
  75.         {   fract lamda;
  76.             
  77.             sweepAng >>= 1;
  78.             FractSineCosine(sweepAng, &lamda);
  79.             midPointAng -= halfIncrementAng; /* reset to end of 45 degree segments */
  80.     /*
  81.       * Begin the short piece if we added OFF points earlier
  82.       */
  83.             if (ptWalker - &aPathPtr->data[0].x > 2) {
  84.                 *ptWalker++ = FractMultiply(FractSineCosine(midPointAng, &cosineValue), halfWidth);
  85.                 *ptWalker++ = FractMultiply(cosineValue, halfHeight);
  86.                 ctrBitMask >>= 1;
  87.             }
  88.             *ptWalker++ = MultiplyDivide(halfWidth, FractSineCosine(midPointAng + sweepAng, &cosineValue), lamda);
  89.             *ptWalker++ = MultiplyDivide(halfHeight, cosineValue, lamda);
  90.             aPathPtr->ctrBits |= ctrBitMask;
  91.         }
  92.     /*
  93.       * Finish with the final ON gxPoint
  94.       */
  95.         *ptWalker++ = FractMultiply(FractSineCosine(startAng + sweep, &cosineValue), halfWidth);
  96.         *ptWalker++ = FractMultiply(cosineValue, halfHeight);
  97.     }
  98. /*
  99.   * Time to make the gxPath
  100.   */
  101.     if (wedge) {
  102.         *ptWalker++ = 0;
  103.         *ptWalker++ = 0;
  104.     }
  105.     {   register Fixed centerX  = (r->right + r->left + 1) >> 1;
  106.         register Fixed centerY  = (r->bottom + r->top + 1) >> 1;
  107.         register short counter = (ptWalker - &aPathPtr->data[0].x) >> 1;
  108.         
  109.         aPathPtr->count = counter;
  110.         for  (counter -= 1; counter >= 0; counter--) {  
  111.             *--ptWalker += centerY;
  112.             *--ptWalker += centerX;
  113.         }
  114.     }
  115. }
  116.  
  117.  
  118. gxShape NewArc(const gxRectangle *r, Fixed startAng, Fixed sweep, boolean wedge)
  119. {
  120.     tmpArcPathType aPath;
  121.     gxShape arcShape;
  122.     
  123.     NilParamReturnNil(r);
  124.     if ((sweep >= ff(360)) || (sweep <= ff(-360)))
  125.         return NewOval(r);
  126.  
  127.     SetArcData(r,startAng,sweep,wedge,&aPath);
  128.     arcShape = NewPath((gxPath *) &aPath);
  129.     
  130.     GXSetShapeFill(arcShape, wedge ? gxSolidFill : gxFrameFill);
  131.     return arcShape;
  132. }
  133.  
  134. void SetArc(gxShape sh, const gxRectangle *r, Fixed startAng, Fixed sweep, boolean wedge)
  135. {
  136.     tmpArcPathType aPath;
  137.  
  138.     NilParamReturn(r);
  139.     
  140.     if ((sweep >= ff(360)) || (sweep <= ff(-360))) SetOval(sh,r);
  141.     else {
  142.         SetArcData(r,startAng,sweep,wedge,&aPath);
  143.         SetPath(sh, 0, (gxPath *) &aPath);
  144.     }
  145. }
  146.  
  147.  
  148. void DrawArc(const gxRectangle *r, Fixed startAng, Fixed sweep, boolean wedge)
  149. {
  150.     gxShape arcShape;
  151.     
  152.     NilParamReturn(r);
  153.     arcShape = NewArc(r, startAng, sweep, wedge);
  154.     GXDrawShape(arcShape);
  155.     GXDisposeShape(arcShape);
  156. }
  157.